home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr23
/
combi113.zip
/
COMBI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-03
|
12KB
|
390 lines
/*
* This program is copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.
*
* The source is supplied as an example of interface to COMBI-disk (C)
* device driver. You may change the source as You wish, however I'm not
* responsible for the results of Your changes.
*
* Exit status:
* 3 - COMBI-disk not found;
* 2 - incorrect usage;
* 1 - can't change options or reallocate buffer;
* 0 - O'K - no errors.
*
* The program is written for MS C 6.0 and may be compiled in TINY or
* SMALL memory model.
*
* I apologize if the code looks cumbersome but I tried to make it most
* compatible with other compilers. (Turbo C 2.0 compiles it O'K).
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <ctype.h>
#include "ioctl.h" /* definitions of structures and control codes */
/* ANSI escape sequences to control colour output. If ANSI is not detected
* all they are changed to point to an empty string. */
char *A_bold = "\x1b[1m";
char *A_red = "\x1b[1;31m";
char *A_yell = "\x1b[1;33m";
char *A_cyan = "\x1b[1;36m";
char *A_norm = "\x1b[0m";
char drive=2;
static void
show_status(struct combi_status *cmb_st)
{
char opt;
printf("\t%sCOMBI-disk version %1d.%02d installed as drive %c:%s\n",
A_yell,
cmb_st->version >> 8, cmb_st->version & 0xff, drive+'A'-1, A_norm);
printf("\n\t%sCurrent status:%s\n", A_bold, A_norm);
printf("buffer size: %s%5dK%s\n", A_cyan, cmb_st -> buff_size, A_norm);
printf("current size: %s%5dK%s\n", A_cyan, cmb_st -> curr_size, A_norm);
printf("total number of blocks: %s%4d%s (%s%d%s sectors each)\n",
A_cyan, cmb_st -> n_blocks, A_norm,
A_cyan, cmb_st -> bl_sect, A_norm);
printf("current number of blocks: %s%4d%s (%s%d%s - RAM disk, %s%d%s - cache)\n",
A_cyan, cmb_st -> n_curr, A_norm,
A_cyan, cmb_st -> n_bl_RD, A_norm,
A_cyan, cmb_st -> n_bl_Cache, A_norm);
opt = cmb_st -> COMBI_options;
if(opt & OPT_WR_ON) { /* only if write caching is on */
printf("dirty blocks: %s%d%s, errors: %s%d%s\n",
A_cyan, cmb_st -> n_dirty, A_norm,
A_cyan, cmb_st -> n_errors, A_norm);
};
printf("\n\t%sOptions in order:%s\n", A_bold, A_norm);
if(!(opt & OPT_OFF)) {
printf("cache is %son%s (%s),\n", A_cyan, A_norm,
(opt & OPT_FREEZE) ? "frozen" : "not frozen");
printf("write caching is %s%s%s,\n", A_cyan,
(opt & OPT_WR_ON) ? "on" : "off", A_norm);
if(opt & OPT_WR_ON) {
printf("delayed write is %s%s%s,\n", A_cyan,
(opt & OPT_DW_OFF) ? "off" : "on", A_norm);
};
} else {
printf("cache is %soff%s,\n", A_cyan, A_norm);
};
printf("memory allocation is %s%s%s.\n", A_cyan,
(opt & OPT_MEM) ? "fixed" : "not fixed", A_norm);
printf("\n\t%sStatistics:%s\n", A_bold, A_norm);
printf("RAM disk reads: %s% 6u/%-6u%s\n",
A_cyan, cmb_st -> read_RD_num, cmb_st -> read_RD_sect, A_norm);
printf("RAM disk writes:%s% 6u/%-6u%s\n", A_cyan,
cmb_st -> write_RD_num, cmb_st -> write_RD_sect, A_norm);
if(!(opt & OPT_OFF)){
printf("Hard disk reads - requested: %s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
A_cyan, cmb_st -> read_rq, cmb_st -> read_sect, A_norm,
A_cyan, cmb_st -> read_rq_a, cmb_st -> read_sect_a, A_norm);
printf("Hard disk writes - requested:%s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
A_cyan, cmb_st -> write_rq, cmb_st -> write_sect, A_norm,
A_cyan, cmb_st -> write_rq_a, cmb_st -> write_sect_a, A_norm);
}
}
static int
change_mem(char drive, int ver, int memch)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
if(memch > 0) {
ctl[2] = CMD_EXPAND; /* command code for COMBI-disk - expand memory */
*(int *)&ctl[3] = memch;/* the amount of Kbytes to change memory size */
} else {
ctl[2] = CMD_SHRINK; /* command code for COMBI-disk - shrink memory */
*(int *)&ctl[3] = - memch;
}
r.x.ax=0x4405; /* DOS function: 'write IOCtl to block device' */
r.h.bl=drive; /* device number */
r.x.dx=(unsigned)&ctl; /* address of IOCtl packet */
r.x.cx=5; /* IOCtl packet length */
intdos(&r,&r);
if(r.x.cflag & 01) /* test for error return code */
return -1;
else
return 0;
}
static int
change_opt(char drive, int ver, char opt)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
ctl[2] = CMD_CH_OPT; /* command to COMBI-disk - change options */
ctl[3] = opt; /* the byte with new options follows the command */
r.x.ax=0x4405;
r.h.bl=drive;
r.x.dx=(unsigned)&ctl;
r.x.cx=4;
intdos(&r,&r);
if(r.x.cflag & 01)
return -1;
else
return 0;
}
static int
reset_counters(char drive, int ver)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
ctl[2] = CMD_RESET_C; /* command to COMBI-disk - reset counters */
ctl[3] = 7; /* reset all three types of counters */
r.x.ax=0x4405;
r.h.bl=drive;
r.x.dx=(unsigned)&ctl;
r.x.cx=4;
intdos(&r,&r);
if(r.x.cflag & 01)
return -1;
else
return 0;
}
static void
usage(void)
{
printf("\t%sCOMBI-disk (C) control program.%s\n"
"Copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.\n",
A_yell, A_norm);
printf("Usage: %sCOMBI [[+|-]#] [<option>[+|-]]...%s\n",
"where:\n", A_bold, A_norm);
printf(" %s# (number)%s - expand or shrink memory used by COMBI-disk,\n",
A_bold, A_norm);
printf(" %sn%s - don't return 'sector not found' error,\n",
A_bold, A_norm);
printf(" %so%s - turn cache on ('%so-%s' - turn off),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sb%s - turn write caching on ('%sb-%s' - off),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %si%s - start writing immediately ('%si-%s' - delayed writing),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sf%s - fix memory settings ('%sf-%s' - release),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sz%s - freeze cache ('%sz-%s' - un-freese),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sr%s - reset all counters.\n",
A_bold, A_norm);
exit(2);
}
static void
chk_ansi(void)
{
union REGS r;
r.x.ax = 0x4400; /* DOS IOCtl - get handle info */
r.x.bx = 0x0001; /* stdout handle */
intdos(&r,&r);
if((r.x.dx & 0x82) == 0x82) {
r.x.ax = 0x1a00;
int86(0x2f, &r, &r);
if(r.h.al == 0xff)
return;
}
/* Else output is redirected into file or ANSI is not installed.
* So, we should turn off escape sequences. */
A_bold = A_yell = A_red = A_cyan = A_norm = "";
}
main(int argc, char *argv[])
{
struct combi_status cmb_st;
union REGS r;
int i,j;
int exitstat=0;
char *chpt, optchar;
char oldopt, opt;
chk_ansi(); /* Determine whether ANSI driver is installed and whether
* the output is redirected to file */
/*
* Scan all drives and try to read IOCtl packet of length sizeof(cmb_st).
* If successful then probably that drive is COMBI's RAM disk. To ensure
* this we check that first 6 bytes of returned packet are "COMBI\0".
*/
do {
drive++;
r.x.ax=0x4404;
r.h.bl=drive;
r.x.cx=sizeof(cmb_st);
r.x.dx=(unsigned)&cmb_st;
} while (((intdos(&r,&r)!=sizeof(cmb_st))||
(r.x.cflag & 0x1)||
strcmp(cmb_st.ID_name,"COMBI"))&&(drive < 16));
if(drive >= 16) {
printf("%sError: COMBI-disk not installed!(?)%s\n", A_red, A_norm);
exit(3);
}
if(argc > 1) { /* any parameters? */
optchar = '\0';
oldopt = opt = cmb_st.COMBI_options;
for(i=1; i < argc; i++) { /* Scan all command line arguments. */
strlwr(argv[i]);
if(isdigit(*argv[i]) || *argv[i]=='-' || *argv[i]=='+') {
/* If an argument is a number then try to reallocate COMBI's
* memory size.*/
j = atoi(argv[i]);
if(change_mem(drive, cmb_st.version, j)) {
printf("%sCan't reallocate memory!%s\a\n", A_red, A_norm);
exitstat = 1;
} else
printf("Memory reallocated by %+dK. ", j);
} else {
optchar = *argv[i];
chpt = argv[i]+1;
while(optchar) {
switch(optchar) {
case 'n':
/* Option 'n' - ignore (or not ignore if 'n-')
* 'sector not found error'. */
if(*chpt == '-') {
opt &= ~OPT_NO_SNF; /* Reset the option bit */
chpt++;
} else {
opt |= OPT_NO_SNF; /* Set the option bit */
if(*chpt == '+')
chpt++;
}
optchar = *chpt++;
break;
case 'o':
/* Option 'o' - turn cache on. */
if(*chpt == '-') {
opt |= OPT_OFF;
chpt++;
} else {
opt &= ~OPT_OFF;
if(*chpt == '+')
chpt++;
}
optchar = *chpt++;
break;
case 'b':
/* Option 'b' - turn background writing
* (== write caching) on. */
if(*chpt == '-') {
opt &= ~OPT_WR_ON;
chpt++;
} else {
opt |= OPT_WR_ON;
if(*chpt == '+')
chpt++;
}
optchar = *chpt++;
break;
case 'i':
/* Option 'i' - write immediately
* (or enable delayed writing if 'i-') in effect only if
* write caching (background writing) is on. */
if(*chpt == '-') {
opt &= ~OPT_DW_OFF;
chpt++;
} else {
opt |= OPT_DW_OFF;
if(*chpt == '+')
chpt++;
}
optchar = *chpt++;
break;
case 'z':
/* Option 'z' - freeze cache - no new sectors are read into
* cache after freezing and only that are in cache may be written
* in background. */
if(*chpt == '-') {
opt &= ~OPT_FREEZE;
chpt++;
} else {
opt |= OPT_FREEZE;
if(*chpt == '+')
chpt++;
}
optchar = *chpt++;
break;
case 'f':
/* Option 'z' - fix memory setting - disables automatic reallocation
* of XMS memory when it is requested by other programs. */
if(*chpt == '-') {
opt &= ~OPT_MEM;
chpt++;
} else {
opt |= OPT_MEM;
if(*chpt == '+')
chpt++;
}
optchar = *chpt;
break;
case 'r':
/* reset all counters */
if(reset_counters(drive, cmb_st.version)) {
printf("%sCan't reset counters!%s\a\n", A_red, A_norm);
exitstat = 1;
} else
printf("Counters reset. ");
optchar = *chpt++;
break;
default:
printf("%sInvalid option: %s'%c'%s\n", A_red, A_bold,
optchar, A_norm);
case '?':
usage();
}
}
}
}
if(oldopt != opt) {
if(change_opt(drive, cmb_st.version, opt)) {
printf("%sCan't change options!%s\a\n", A_red, A_norm);
exitstat = 1;
} else
printf("Options changed.");
} else
printf("Options unchanged.");
printf("\n");
} else { /* no arguments */
show_status(&cmb_st); /* Show status returned by COMBI. */
}
return exitstat;
}